package com.dc.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dc.common.DateUtil;
import com.dc.common.ResponseResultVO;
import com.dc.entity.*;
import com.dc.entity.ro.InspectionWorkOrderRO;
import com.dc.entity.vo.InspectionVO;
import com.dc.entity.vo.RoutePositionVO;
import com.dc.enums.OrderType;
import com.dc.mapper.*;
import com.dc.service.InspectionWorkOrderService;
import com.dc.util.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static com.dc.common.ResponseResultVO.*;

@Service
public class InspectionWorkOrderServiceImpl implements InspectionWorkOrderService {
    @Resource
    private WorkOrderMapper workOrderMapper;
    @Resource
    private InspectionWorkOrderRelationMapper workOrderRelationMapper;
    @Resource
    private QrCodeManagementMapper qrCodeManagementMapper;
    @Resource
    private InspectionPositionMapper positionMapper;
    @Resource
    private InspectionRouteMapper routeMapper;
    @Resource
    private InspectionRelationMapper inspectionRelationMapper;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private RegionMapper regionMapper;


    @Override
    @Transactional
    public ResponseResultVO insertInspectionWorkOrder(InspectionWorkOrderRO ro) {
        //当前用户以及路线并且状态为巡检中的数据
        List<WorkOrder> inspectionWorkOrders = workOrderMapper.selectList(new QueryWrapper<WorkOrder>().lambda()
                .eq(WorkOrder::getRouteId, ro.getRouteId()).eq(WorkOrder::getUserId, UserUtil.getUserId()).eq(WorkOrder::getStatus, 0));
        int i = 0;
        if (CollectionUtils.isEmpty(inspectionWorkOrders)) {
            //如果为空，说明不存在巡检中的工单，之前巡检均已完成，当前巡检是新的开始
            WorkOrder inspectionWorkOrder = new WorkOrder();
            BeanUtils.copyProperties(ro, inspectionWorkOrder);
            inspectionWorkOrder.setId(SnowflakeIdWorker.generateId());
            inspectionWorkOrder.setUserId(Long.valueOf(UserUtil.getUserId()));
            inspectionWorkOrder.setUserName(String.valueOf(redisUtil.get(UserUtil.getUserId())));
            inspectionWorkOrder.setReportUserId(Long.valueOf(UserUtil.getUserId()));
            inspectionWorkOrder.setReportUserName(String.valueOf(redisUtil.get(UserUtil.getUserId())));
            inspectionWorkOrder.setUserId(Long.valueOf(UserUtil.getUserId()));
            inspectionWorkOrder.setUserName(String.valueOf(redisUtil.get(UserUtil.getUserId())));
            inspectionWorkOrder.setType(OrderType.INSPECTION.getId());
            inspectionWorkOrder.setStartTime(new Date());
            Integer count = inspectionRelationMapper.selectCount(new QueryWrapper<InspectionRelation>().lambda().eq(InspectionRelation::getRouteId, ro.getRouteId()));
            if (0 == count) {
                return failResult("当前路线下面没有点位,请联系管理员");
            } else if (1 == count) {
                inspectionWorkOrder.setStatus(2);
                inspectionWorkOrder.setEndTime(new Date());
            }
            inspectionWorkOrder.setNeedNum(count);
            inspectionWorkOrder.setAlreadyNum(1);
            workOrderMapper.insert(inspectionWorkOrder);
            InspectionWorkOrderRelation inspectionWorkOrderRelation = new InspectionWorkOrderRelation();
            BeanUtils.copyProperties(ro, inspectionWorkOrderRelation);
            inspectionWorkOrderRelation.setId(SnowflakeIdWorker.generateId());
            inspectionWorkOrderRelation.setWordOrderId(inspectionWorkOrder.getId());
            inspectionWorkOrderRelation.setRemark(ro.getDescription());
            i = workOrderRelationMapper.insert(inspectionWorkOrderRelation);
        } else {
            //如果已经存在数据,说明还有之前未完成的巡检任务
            WorkOrder inspectionWorkOrder = inspectionWorkOrders.get(0);
            //判断当前点位是否已经巡检过
            InspectionWorkOrderRelation orderRelation = workOrderRelationMapper.selectOne(new QueryWrapper<InspectionWorkOrderRelation>().lambda()
                    .eq(InspectionWorkOrderRelation::getWordOrderId, inspectionWorkOrder.getId())
                    .and(wrapper -> wrapper.eq(InspectionWorkOrderRelation::getPositionName, ro.getPositionName())
                            .or().eq(InspectionWorkOrderRelation::getPositionId, ro.getPositionId())));
            if (null != orderRelation) {
                return failResult("当前点位已经完成巡检,请勿重复提交");
            }
            Integer count = workOrderRelationMapper.selectCount(new QueryWrapper<InspectionWorkOrderRelation>().lambda().eq(InspectionWorkOrderRelation::getWordOrderId, inspectionWorkOrder.getId()));
            inspectionWorkOrder.setAlreadyNum(inspectionWorkOrder.getAlreadyNum() + 1);
            //满足情况，则设置status为完成，并且添加最后巡检时间
            if (inspectionWorkOrder.getNeedNum() - 1 == count) {
                inspectionWorkOrder.setStatus(2);
                inspectionWorkOrder.setEndTime(new Date());
            }
            workOrderMapper.updateById(inspectionWorkOrder);
            InspectionWorkOrderRelation inspectionWorkOrderRelation = new InspectionWorkOrderRelation();
            BeanUtils.copyProperties(ro, inspectionWorkOrderRelation);
            inspectionWorkOrderRelation.setId(SnowflakeIdWorker.generateId());
            inspectionWorkOrderRelation.setWordOrderId(inspectionWorkOrder.getId());
            inspectionWorkOrderRelation.setRemark(ro.getDescription());
            i = workOrderRelationMapper.insert(inspectionWorkOrderRelation);
        }
        return ResponseResultVO.insertResult(i);
    }

    /**
     * 巡检上报
     *
     * @param ro
     * @return
     */
    @Override
    @Transactional
    public ResponseResultVO newInsertInspectionWorkOrder(InspectionWorkOrderRO ro) {
        if (ObjectUtil.isEmpty(ro.getRegionIds()) || ObjectUtil.isNull(ro.getRegionIds())) {
            return ResponseResultVO.failResult("巡检区域不能为空");
        }
        List<InspectionWorkOrderRelation> relations = workOrderRelationMapper.selectList(new QueryWrapper<InspectionWorkOrderRelation>().lambda()
                .in(InspectionWorkOrderRelation::getRegionId, ro.getRegionIds()));
        HashSet<String> hashSet = new HashSet<>();
        for (InspectionWorkOrderRelation relation : relations) {
            WorkOrder order = workOrderMapper.selectOne(new QueryWrapper<WorkOrder>().lambda()
                    .eq(WorkOrder::getId, relation.getWordOrderId())
                    .eq(WorkOrder::getUserId, UserUtil.getUserId())
                    .eq(WorkOrder::getStatus, 0));
            if (order != null) {
                hashSet.add(relation.getRegionName());
            }
        }
        if (!hashSet.isEmpty() && hashSet.size() > 0) {
            String collect = new ArrayList<>(hashSet).stream().collect(Collectors.joining(","));
            return ResponseResultVO.failResult(String.format("巡检区域【%s】还未完成,不能重复登记", collect));
        }

        WorkOrder inspectionWorkOrder = new WorkOrder();
        // 编号
        Long wordId = SnowflakeIdWorker.generateId();
        BeanUtils.copyProperties(ro, inspectionWorkOrder);
        inspectionWorkOrder.setId(wordId);
        inspectionWorkOrder.setUserId(Long.valueOf(UserUtil.getUserId()));
        inspectionWorkOrder.setUserName(String.valueOf(redisUtil.get(UserUtil.getUserId())));
        inspectionWorkOrder.setReportUserId(Long.valueOf(UserUtil.getUserId()));
        inspectionWorkOrder.setReportUserName(String.valueOf(redisUtil.get(UserUtil.getUserId())));
        inspectionWorkOrder.setType(OrderType.INSPECTION.getId());
        inspectionWorkOrder.setStartTime(DateUtil.parseStrToDate(ro.getStartTime(), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS));
        inspectionWorkOrder.setEndTime(DateUtil.parseStrToDate(ro.getEndTime(), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS));
        inspectionWorkOrder.setDescription(ro.getDescription());

        int flag = 0;
        for (Long aLong : ro.getRegionIds()) {
            // dc_inspection_work_order_relation  巡检区域中间表
            InspectionWorkOrderRelation orderRelation = new InspectionWorkOrderRelation();
            orderRelation.setId(SnowflakeIdWorker.generateId());
            orderRelation.setWordOrderId(wordId);
            orderRelation.setInspectionResult(0);
            orderRelation.setRegionId(aLong);
            orderRelation.setRegionName(regionMapper.selectById(aLong).getRegionName());
            flag = workOrderRelationMapper.insert(orderRelation);
        }
        int insert = workOrderMapper.insert(inspectionWorkOrder);
        return ResponseResultVO.insertResult(insert & flag);
    }

    @Override
    public ResponseResultVO updateInspectionWorkOrder(InspectionWorkOrderRO ro) {
        checkParameterIsNotNull(String.valueOf(ro.getId()), "id不能为空");
        WorkOrder inspectionWorkOrder = new WorkOrder();
        BeanUtils.copyProperties(ro, inspectionWorkOrder);
        return ResponseResultVO.updateResult(workOrderMapper.updateById(inspectionWorkOrder));
    }

    @Override
    public ResponseResultVO deleteInspectionWorkOrder(String ids) {
        checkParameterIsNotNull(ids, "id不能为空");
        List<String> idList = Arrays.asList(ids.split(","));
        return ResponseResultVO.deleteResult(workOrderMapper.deleteBatchIds(idList));
    }

    @Override
    public ResponseResultVO selectWorkOrderByPage(InspectionWorkOrderRO ro) {
        Page page = new Page<Map<String, Object>>(ro.getCurrentPage(), ro.getPageSize());
        QueryWrapper<WorkOrder> queryWrapper = new QueryWrapper<>();
        //点位
        /*if (StringUtils.isNotBlank(ro.getPositionName())) {
            List<InspectionWorkOrderRelation> workOrderRelations = workOrderRelationMapper.selectList(new QueryWrapper<InspectionWorkOrderRelation>().lambda().like(InspectionWorkOrderRelation::getPositionName, ro.getPositionName()));
            if (CollectionUtils.isNotEmpty(workOrderRelations)) {
                queryWrapper.lambda().in(WorkOrder::getId, workOrderRelations.stream().map(InspectionWorkOrderRelation::getWordOrderId).collect(Collectors.toSet()));
            }
        }*/
        // 区域位置
        /*if (StringUtils.isNotBlank(ro.getRegionName())) {
            List<InspectionWorkOrderRelation> inspectionWorkOrderRelations = workOrderRelationMapper.selectList(new QueryWrapper<InspectionWorkOrderRelation>().lambda().eq(InspectionWorkOrderRelation::getRegionName, ro.getRegionName()));
            if (CollectionUtils.isNotEmpty(inspectionWorkOrderRelations)) {
                Set<Long> workOderIds = inspectionWorkOrderRelations.stream().map(InspectionWorkOrderRelation::getWordOrderId).collect(Collectors.toSet());
                queryWrapper.lambda().in(WorkOrder::getId, workOderIds);
            }
        }*/
        //是否是H5
        if (StringUtils.isNotBlank(ro.getClient()) && "H5".equalsIgnoreCase(ro.getClient())) {
            queryWrapper.lambda().eq(WorkOrder::getReportUserId, UserUtil.getUserId());
        }
        queryWrapper.apply(StrUtil.isNotBlank(ro.getCreateTime()),
                "date_format (create_time,'%Y-%m-%d') = date_format('" + ro.getCreateTime() + "','%Y-%m-%d')");

        queryWrapper.lambda().eq(WorkOrder::getType, OrderType.INSPECTION.getId());
        queryWrapper.lambda().eq(null != ro.getStatus(), WorkOrder::getStatus, ro.getStatus());
        queryWrapper.lambda().eq(null != ro.getUserId(), WorkOrder::getUserId, ro.getUserId());
        queryWrapper.lambda().like(StringUtils.isNotBlank(ro.getRouteName()), WorkOrder::getRouteName, ro.getRouteName());
        queryWrapper.lambda().ge(StringUtils.isNotBlank(ro.getStartTime()), WorkOrder::getStartTime, ro.getStartTime());
        queryWrapper.lambda().le(StringUtils.isNotBlank(ro.getEndTime()), WorkOrder::getEndTime, ro.getEndTime());
        queryWrapper.lambda().like(StringUtils.isNotBlank(ro.getUserName()), WorkOrder::getUserName, ro.getUserName());
        queryWrapper.lambda().orderByDesc(WorkOrder::getCreateTime);

        Page<WorkOrder> selectPage = workOrderMapper.selectPage(page, queryWrapper);
        List<InspectionVO> inspectionVOS = ListBeanUtils.listCopyMapper(selectPage.getRecords(), WorkOrder.class, InspectionVO.class);
        inspectionVOS.forEach(s -> {
            // s.setNotNum(s.getNeedNum() - s.getAlreadyNum());
            List<String> strings = retRegionName(String.valueOf(s.getId()));
            List<Long> longs = retRegionId(String.valueOf(s.getId()));
            s.setRegionId(longs.stream().map(String::valueOf).collect(Collectors.joining(",")));
            s.setRegionName(strings.stream().collect(Collectors.joining(",")));
        });
        // 总数
        ro.setTotalCount(workOrderMapper.selectCount(queryWrapper));
        return ResponseResultVO.resultPageList(inspectionVOS, ro);
    }

    @Override
    public ResponseResultVO selectWorkOrderDetailByPage(InspectionWorkOrderRO ro) {
        checkParameterIsNotNull(String.valueOf(ro.getId()), "id不能为空");
        Page page = new Page<Map<String, Object>>(ro.getCurrentPage(), ro.getPageSize());
        QueryWrapper<InspectionWorkOrderRelation> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(null != ro.getInspectionResult(), InspectionWorkOrderRelation::getInspectionResult, ro.getInspectionResult());
        queryWrapper.lambda().eq(null != ro.getId(), InspectionWorkOrderRelation::getWordOrderId, ro.getId());
        queryWrapper.apply(StrUtil.isNotBlank(ro.getCreateTime()),
                "date_format (create_time,'%Y-%m-%d') = date_format('" + ro.getCreateTime() + "','%Y-%m-%d')");
        //巡检时间区间查询
        queryWrapper.apply(StrUtil.isNotBlank(ro.getStartTime()),
                "date_format (create_time,'%Y-%m-%d') >= date_format('" + ro.getStartTime() + "','%Y-%m-%d')");
        queryWrapper.apply(StrUtil.isNotBlank(ro.getEndTime()),
                "date_format (create_time,'%Y-%m-%d') < date_format('" + ro.getEndTime() + "','%Y-%m-%d')");
        queryWrapper.lambda().orderByDesc(InspectionWorkOrderRelation::getCreateTime);
        return ResponseResultVO.resultList(workOrderRelationMapper.selectPage(page, queryWrapper), ro);
    }

    @Override
    public void inspectionRouteListExport(HttpServletResponse response, InspectionWorkOrderRO ro) {
        ResponseResultVO roadReportForm = this.selectWorkOrderByPage(ro);
        HashMap<String, Object> data = (HashMap<String, Object>) roadReportForm.getData();
        ExportUtil.exportExcelNew("巡检记录", (List) data.get("list"), InspectionVO.class, response);
    }

    // TODO 可能一个点位查出来多条路线
    @Override
    public ResponseResultVO qrCodeVerification(String id) {
        if (StringUtils.isBlank(id)) {
            return failResult("请扫描二维码");
        }
        QrCodeManagement qrCodeManagement = qrCodeManagementMapper.selectById(id);
        if (null == qrCodeManagement) {
            return failResult("此二维码已作废");
        }
        RoutePositionVO routePositionVO = new RoutePositionVO();
        InspectionPosition inspectionPosition = positionMapper.selectOne(new QueryWrapper<InspectionPosition>().lambda().eq(InspectionPosition::getQrId, id));
        if (null != inspectionPosition) {
            List<InspectionRelation> inspectionRelations = inspectionRelationMapper.selectList(
                    new QueryWrapper<InspectionRelation>().lambda().eq(InspectionRelation::getPositionId, inspectionPosition.getId()));
//            if (CollectionUtils.isEmpty(inspectionRelations)) {
//                //通过id查询该二维码状态,如果二维码状态为已使用,且没有绑定路线，提示已失效
//                return failResult("此二维码已失效");
//            }
            //点位信息
            routePositionVO.setAddress(inspectionPosition.getAddress());
            routePositionVO.setRegionId(inspectionPosition.getRegionId());
            routePositionVO.setRegionName(inspectionPosition.getRegionName());
            routePositionVO.setPositionId(inspectionPosition.getId());
            routePositionVO.setPositionName(inspectionPosition.getName());
            //路线信息
            if (CollectionUtils.isNotEmpty(inspectionRelations)) {
                List<InspectionRoute> list = new ArrayList<>();
                for (InspectionRelation dto : inspectionRelations) {
                    InspectionRoute inspectionRoute = routeMapper.selectById(dto.getRouteId());
                    InspectionRoute route = new InspectionRoute();
                    route.setId(inspectionRoute.getId());
                    route.setName(inspectionRoute.getName());
                    list.add(route);
                }
                routePositionVO.setRouteInfo(list);
            }
        }
        return successResult(routePositionVO);
    }

    @Override
    public ResponseResultVO selectInspectionWorkOrder(String id) {
        // 巡检工单信息
        WorkOrder workOrder = workOrderMapper.selectById(id);
        // 对应的巡检区域
        workOrder.setRegionIds(retRegionName(id));
        return ResponseResultVO.successResult(workOrder);
    }

    private List<String> retRegionName(String id) {
        List<String> collect = workOrderRelationMapper.selectList(new LambdaQueryWrapper<InspectionWorkOrderRelation>()
                .eq(InspectionWorkOrderRelation::getWordOrderId, id))
                .stream().map(InspectionWorkOrderRelation::getRegionName)
                .collect(Collectors.toList());
        return collect;
    }

    private List<Long> retRegionId(String id) {
        List<Long> collect = workOrderRelationMapper.selectList(new LambdaQueryWrapper<InspectionWorkOrderRelation>()
                .eq(InspectionWorkOrderRelation::getWordOrderId, id))
                .stream().map(InspectionWorkOrderRelation::getRegionId)
                .collect(Collectors.toList());
        return collect;
    }

}
